package pers.bc.utils.yonyou;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import nc.bs.dao.BaseDAO;
import nc.bs.framework.common.InvocationInfoProxy;
import nc.bs.framework.common.NCLocator;
import nc.bs.pf.pub.PfDataCache;
import nc.processor.MapFieldProcessor;
import nc.pub.tools.ProcessorUtils;
import nc.pubitf.fip.service.IFipMessageService;
import nc.util.pub.SqlUtil;
import nc.vo.fip.relation.FipRelationVO;
import nc.vo.fip.service.FipMessageVO;
import nc.vo.fip.service.FipMsgResultVO;
import nc.vo.fip.service.FipRelationInfoVO;
import nc.vo.pub.BusinessException;
import nc.vo.pub.SuperVO;
import nc.vo.pub.lang.UFDate;
import nc.vo.pubapp.pattern.model.entity.bill.AbstractBill;
import nc.vo.pubapp.pattern.model.entity.bill.IBill;
import pers.bc.utils.pub.JudgeAssertUtil;
import pers.bc.utils.pub.LoggerUtil;

/**
 * *********************************************************** <br>
 * *说明： 发送总账，凭证生成，凭证取消 <br>
 * @see <br>
 * @return <br>
 * @SendVoucherTool <br>
 * @methods ncc.itf.tr.pub.SendVoucherTool#getInstance2 <br>
 * @author LiBencheng <br>
 * @date Created on 2020年8月4日 <br>
 * @time 16:59:48 <br>
 * @version 1.0 <br>
 *************************************************************          <br>
 */
public class SendVoucherUtil
{
    
    String folderName = "sendVouchLos";
    LoggerUtil logUtil = LoggerUtil.getInstance(folderName);
    
    private static SendVoucherUtil instance;
    private static ThreadLocal<SendVoucherUtil> sendVoucher = new ThreadLocal<SendVoucherUtil>();
    
    /**
     * *********************************************************** <br>
     * *说明：线程隔离 <br>
     * @see <br>
     * @return <br>
     * @SendVoucherTool <br>
     * @methods ncc.itf.tr.pub.SendVoucherTool#getInstance2 <br>
     * @author LiBencheng <br>
     * @date Created on 2025年8月4日 <br>
     * @time 17:01:48 <br>
     * @version 1.0 <br>
     *************************************************************          <br>
     */
    public static SendVoucherUtil getInstance2()
    {
        SendVoucherUtil df = (SendVoucherUtil) sendVoucher.get();
        synchronized (SendVoucherUtil.class)
        {
            if (df == null)
            {
                df = new SendVoucherUtil();
                sendVoucher.set(df);
            }
            
            return df;
        }
    }
    
    /**
     * *********************************************************** <br>
     * *说明： 单例实现 <br>
     * @see <br>
     * @return <br>
     * @SendVoucherTool <br>
     * @methods ncc.itf.tr.pub.SendVoucherTool#getInstance <br>
     * @author LiBencheng <br>
     * @date Created on 2025年8月4日 <br>
     * @time 16:10:55 <br>
     * @version 1.0 <br>
     *************************************************************          <br>
     */
    public static synchronized SendVoucherUtil getInstance()
    {
        if (instance == null) instance = new SendVoucherUtil();
        return instance;
    }
    
    public SendVoucherUtil()
    {
    }
    
    /**
     * *********************************************************** <br>
     * *说明： 主子表单据vo发送会计平台<br>
     * @see <br>
     * @param msgvos
     * @return
     * @throws Exception <br>
     * @FipMsgResultVO[] <br>
     * @methods ncc.itf.tr.pub.SendVoucherTool#sendMessage <br>
     * @author LiBencheng <br>
     * @date Created on 2025年8月4日 <br>
     * @time 16:11:13 <br>
     * @version 1.0 <br>
     *************************************************************          <br>
     */
    public FipMsgResultVO[] sendMessage(FipMessageVO[] msgvos) throws Exception
    {
        try
        {
            // 发消息到平台
            IFipMessageService ifip = (IFipMessageService) NCLocator.getInstance().lookup(IFipMessageService.class.getName());
            return ifip.sendMessages(msgvos);
        }
        catch (Exception e)
        {
            /**
             * 批量删除方式 汇总消息类型 YangJie 2014-03-25 后续修改
             */
            // String billtype = infoVo.getProc();
            // String bill_code = infoVo.getBillCode();
            // String message = "单据类型：" + billtype + " ,单据号：" + bill_code
            // + " 发送会计平台失败！以下是会计平台错误信息：\t\n" + e.getMessage();
            // throw new BusinessException(e.getMessage());
            JudgeAssertUtil.throwExceptionDir(e, folderName);
        }
        
        return null;
    }
    
    /**
     * *********************************************************** <br>
     * *说明：删除凭证消息 <br>
     * @see <br>
     * @param billVOs
     * @throws Exception <br>
     * @void <br>
     * @methods ncc.itf.tr.pub.SendVoucherTool#deleteRTVoucher <br>
     * @author LiBencheng <br>
     * @date Created on 2025年8月4日 <br>
     * @time 16:11:20 <br>
     * @version 1.0 <br>
     *************************************************************          <br>
     */
    public void deleteRTVoucher(IBill[] billVOs) throws Exception
    {
        // 删除发送到会计平台的消息
        if (billVOs != null)
        {// 根据单据id删除消息
            FipMessageVO[] fipmsgvos = createFipMessage(FipMessageVO.MESSAGETYPE_DEL, billVOs);
            sendMessage(fipmsgvos);
        }
    }
    
    /**
     * *********************************************************** <br>
     * *说明： 增加凭证消息 <br>
     * @see <br>
     * @param billVOs
     * @throws Exception <br>
     * @void <br>
     * @methods ncc.itf.tr.pub.SendVoucherTool#addRTVoucher <br>
     * @author LiBencheng <br>
     * @date Created on 2025年8月4日 <br>
     * @time 16:11:27 <br>
     * @version 1.0 <br>
     *************************************************************          <br>
     */
    public void addRTVoucher(IBill[] billVOs) throws Exception
    {
        // 增加发送到会计平台的消息
        if (billVOs != null)
        {// 根据单据id删除消息
            FipMessageVO[] fipmsgvos = createFipMessage(FipMessageVO.MESSAGETYPE_ADD, billVOs);
            sendMessage(fipmsgvos);
        }
        
    }
    
    /**
     * *********************************************************** <br>
     * *说明： 构建会计平台消息 <br>
     * @see <br>
     * @param messagetype
     * @param billVOs
     * @return
     * @throws BusinessException <br>
     * @FipMessageVO[] <br>
     * @methods ncc.itf.tr.pub.SendVoucherTool#createFipMessage <br>
     * @author LiBencheng <br>
     * @date Created on 2025年8月4日 <br>
     * @time 16:11:37 <br>
     * @version 1.0 <br>
     *************************************************************          <br>
     */
    protected FipMessageVO[] createFipMessage(int messagetype, IBill[] billVOs) throws BusinessException
    {
        List<FipMessageVO> fipMessageVOs = new ArrayList<FipMessageVO>();
        for (int i = 0; i < billVOs.length; i++)
        {
            SuperVO headVO = (SuperVO) ((AbstractBill) billVOs[i]).getParentVO();
            
            FipMessageVO fipMessageVO = new FipMessageVO();
            
            fipMessageVO.setBillVO(billVOs[i]);
            
            fipMessageVO.setMessagetype(messagetype);
            FipRelationInfoVO infoVO = createFipRelationInfoVO(billVOs[i]);
            if (messagetype == FipMessageVO.MESSAGETYPE_ADD)
            {
                String auditor = (String) headVO.getAttributeValue("vapproveid");// 审核人
                // UFDateTime audittime = (UFDateTime) headVO.getAttributeValue("dapprovedate");//审核日期 待修改
                // YangJie2014=03-25
                // UFDate date = audittime.getDate();
                UFDate date = (UFDate) headVO.getAttributeValue("dapprovedate");// 审核日期 待修改 YangJie2014=03-25
                if (auditor != null)
                {
                    infoVO.setPk_operator(auditor);
                }
                else
                    infoVO.setPk_operator(InvocationInfoProxy.getInstance().getUserId());
                if (date != null) infoVO.setBusidate(date);
            }
            else if (messagetype == FipMessageVO.MESSAGETYPE_DEL)
            {
                infoVO.setPk_operator(InvocationInfoProxy.getInstance().getUserId());
            }
            fipMessageVO.setMessageinfo(infoVO);
            fipMessageVOs.add(fipMessageVO);
        }
        
        return fipMessageVOs.toArray(new FipMessageVO[0]);
    }
    
    /**
     * *********************************************************** <br>
     * *说明： 具体信息 <br>
     * @see <br>
     * @param billVO
     * @return <br>
     * @FipRelationInfoVO <br>
     * @methods ncc.itf.tr.pub.SendVoucherTool#createFipRelationInfoVO <br>
     * @author LiBencheng <br>
     * @date Created on 2014年8月4日 <br>
     * @time 16:11:54 <br>
     * @version 1.0 <br>
     *************************************************************          <br>
     */
    protected FipRelationInfoVO createFipRelationInfoVO(IBill billVO)
    {
        SuperVO headVO = (SuperVO) ((AbstractBill) billVO).getParentVO();
        /**
         * 具体信息 待修改 YangJie2014=03-25
         */
        String billtypecode = (String) headVO.getAttributeValue("pk_busitype");
        if (billtypecode == null || billtypecode.length() == 0)
        {
            billtypecode = (String) headVO.getAttributeValue("pk_billtype");
        }
        FipRelationInfoVO infoVO = new FipRelationInfoVO();
        infoVO.setPk_group((String) headVO.getAttributeValue("pk_group"));
        infoVO.setPk_org((String) headVO.getAttributeValue("pk_org"));
        if (headVO.getAttributeValue("systemcode") == null || headVO.getAttributeValue("systemcode").toString().length() == 0)
            infoVO.setPk_system(PfDataCache.getBillType(billtypecode).getSystemcode());
        else
            infoVO.setPk_system(headVO.getAttributeValue("systemcode").toString());
        infoVO.setPk_billtype(billtypecode);
        
        infoVO.setRelationID(headVO.getPrimaryKey());
        infoVO.setPk_operator(InvocationInfoProxy.getInstance().getUserId());
        infoVO.setFreedef1((String) headVO.getAttributeValue("vbillcode"));
        infoVO.setDefdoc1(billtypecode);// pk_busitype
        
        infoVO.setBusidate(new UFDate());
        infoVO.setFreedef3("0");
        infoVO.setFreedef4("vuserdef4");
        infoVO.setFreedef5("vuserdef5");
        
        return infoVO;
    }
    
    /**
     * *********************************************************** <br>
     * *说明： 查询凭证信息<br>
     * @see <br>
     * @param pks
     * @param billtype
     * @return
     * @throws BusinessException <br>
     * @Map<String,String> <br>
     * @methods ncc.itf.tr.pub.SendVoucherTool#queryVoucherID <br>
     * @author LiBencheng <br>
     * @date Created on 2025年8月4日 <br>
     * @time 16:12:02 <br>
     * @version 1.0 <br>
     *************************************************************          <br>
     */
    public Map<String, String> queryVoucherID(List<String> pks, String billtype) throws BusinessException
    {
        // List<FipRelationVO> reList = null;
        // if(pks == null || pks.size() == 0) return reList;
        // BaseDAO dao = new BaseDAO();
        // reList = (List<FipRelationVO>)dao.executeQuery("select
        // "+FipRelationVO.SRC_RELATIONID+","+FipRelationVO.DES_RELATIONID+" from " +
        // FipRelationVO.getDefaultTableName() +
        // " where " + FipRelationVO.SRC_BILLTYPE + " = " + billtype + " and " +
        // SqlUtil.getSqlInExpr(pks.toArray(new String[0]), FipRelationVO.SRC_RELATIONID, true) + "and
        // isnull(dr,0) = 0 ", new BeanListProcessor(FipRelationVO.class));
        // return reList;
        
        Map<String, String> reMap = new HashMap<String, String>();
        if (pks == null || pks.size() == 0) return reMap;
        BaseDAO dao = new BaseDAO();
        String sql = "select " + FipRelationVO.SRC_RELATIONID + "," + FipRelationVO.DES_RELATIONID + " from "
            + FipRelationVO.getDefaultTableName() + " where " + FipRelationVO.SRC_BILLTYPE + " = '" + billtype + "' and "
            + SqlUtil.getSqlInExpr(pks.toArray(new String[0]), FipRelationVO.SRC_RELATIONID, true) + "and isnull(dr,0) = 0 ";
        reMap = (Map<String, String>) dao.executeQuery(sql, new MapFieldProcessor());
        return reMap;
    }
    
    /**
     * *********************************************************** <br>
     * *说明：获取凭证信息用于回写 <br>
     * @see <br>
     * @param pk_voucher
     * @return
     * @Map <br>
     * @methods ncc.impl.tr.pub.NCC_Impl_VoucherService#getGlVoucher <br>
     * @author LiBencheng <br>
     * @date Created on 2025年8月4日 <br>
     * @time 16:57:17 <br>
     * @throws BusinessException
     * @version 1.0 <br>
     *************************************************************          <br>
     */
    public Map getGlVoucher(String pk_voucher) throws BusinessException
    {
        {
            
            String sql = "  SELECT pk_voucher,pk_accountingbook as pk_accountbook,pk_vouchertype,year,period"//
                + ",num,num as voucher_no,prepareddate as voucher_date,explanation as summary,voucherkind,"//
                + "pk_vouchertype as pk_vouchertype,year as year,period as period,adjustperiod as adjust, "//
                + "pk_setofbook FROM gl_voucher a WHERE a.pk_voucher='" + pk_voucher + "'";
            return (Map) nc.bs.framework.common.NCLocator.getInstance().lookup(nc.itf.uap.IUAPQueryBS.class)//
                .executeQuery(sql, new nc.jdbc.framework.processor.ResultSetProcessor()
                {
                    @Override
                    public Object handleResultSet(ResultSet rs) throws SQLException
                    {
                        return rs.next() ? ProcessorUtils.toMap(rs) : null;
                    }
                });
        }
    }
    
}
